package com.yuqq;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.*;


public class ExcelDeduplication4 {

    // 是否忽略大小写（根据需求调整，如 true 则统一转大写/小写）
    private static final boolean IGNORE_CASE = true;
    public static void main(String[] args) {
        // 输入 Excel 文件路径，需替换为实际路径
        String inputPath = "src/main/resources/output88.xlsx";
        // 输出 Excel 文件路径，需替换为实际路径
        String outputPath = "src/main/resources/output88.xlsx";

        try (Workbook workbook = new XSSFWorkbook(new FileInputStream(inputPath))) {
            Sheet sheet = workbook.getSheetAt(0);
            Map<String, List<RowInfo>> firstColumnMap = new HashMap<>();

            // 1. 遍历所有行，按第一列内容分组，并记录第二列是否有值
            for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) continue;

                // 获取第一列的值作为分组依据
                String firstColumnValue = getCellValueAsString(row.getCell(0));
                // 判断第二列是否有值
                boolean hasSecondColumnValue = hasValue(row.getCell(1));

                firstColumnMap.computeIfAbsent(firstColumnValue, k -> new ArrayList<>())
                        .add(new RowInfo(rowIndex, hasSecondColumnValue));
            }

            // 2. 找出需要删除的行（第二列无值且第一列重复的行）
            List<Integer> rowsToDelete = new ArrayList<>();
            for (Map.Entry<String, List<RowInfo>> entry : firstColumnMap.entrySet()) {
                List<RowInfo> rows = entry.getValue();
                if (rows.size() <= 1) continue; // 无重复，跳过

                // 检查是否同时存在第二列有值和无值的情况
                boolean hasValue = false;
                boolean hasNoValue = false;
                for (RowInfo rowInfo : rows) {
                    if (rowInfo.hasSecondColumnValue) hasValue = true;
                    else hasNoValue = true;

                    if (hasValue && hasNoValue) break; // 已确定存在混合情况，提前退出
                }

                // 如果同时存在有值和无值的情况，删除所有无值的行
                if (hasValue && hasNoValue) {
                    for (RowInfo rowInfo : rows) {
                        if (!rowInfo.hasSecondColumnValue) {
                            rowsToDelete.add(rowInfo.rowIndex);
                        }
                    }
                }
            }

            // 3. 从后往前删除标记的行
            Collections.sort(rowsToDelete, Collections.reverseOrder());
            for (int rowIndex : rowsToDelete) {
                deleteRow(sheet, rowIndex);
            }

            // 4. 保存结果
            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                workbook.write(fos);
            }
            System.out.println("处理完成，已删除 " + rowsToDelete.size() + " 行数据");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获取单元格值的字符串表示（处理各种类型）
    private static String getCellValueAsString(Cell cell) {
        if (cell == null) return "";
        String value;
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getLocalDateTimeCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 公式结果按实际值处理
                // 公式结果按实际值处理
                switch (cell.getCachedFormulaResultType()) {
                    case NUMERIC:
                        value = String.valueOf(cell.getNumericCellValue()).trim();
                        break;
                    case STRING:
                        value = cell.getStringCellValue().trim();
                        break;
                    case BOOLEAN:
                        value = String.valueOf(cell.getBooleanCellValue()).trim();
                        break;
                    case ERROR:
                        value = "[ERROR]";
                        break;
                    default:
                        value = "";
                }
                break;
            default:
                return "";
        }
        // 忽略大小写（统一转大写）
        return IGNORE_CASE ? value.toUpperCase() : value;
    }

    // 判断单元格是否有值（非空且非空白）
    private static boolean hasValue(Cell cell) {
        if (cell == null) return false;

        CellType type = cell.getCellType();
        return type != CellType.BLANK && type != CellType._NONE;
    }

    // 删除指定行
    private static void deleteRow(Sheet sheet, int rowIndex) {
        int lastRowNum = sheet.getLastRowNum();
        if (rowIndex >= 0 && rowIndex < lastRowNum) {
            sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
        } else if (rowIndex == lastRowNum) {
            Row row = sheet.getRow(rowIndex);
            if (row != null) {
                sheet.removeRow(row);
            }
        }
    }

    // 行信息类：记录行号和第二列是否有值
    static class RowInfo {
        int rowIndex;
        boolean hasSecondColumnValue;

        public RowInfo(int rowIndex, boolean hasSecondColumnValue) {
            this.rowIndex = rowIndex;
            this.hasSecondColumnValue = hasSecondColumnValue;
        }
    }
}
